package org.linlinjava.litemall.core.express;

import org.linlinjava.litemall.core.express.config.ExpressProperties;
import org.linlinjava.litemall.core.util.HttpUtil;
import org.springframework.util.Base64Utils;

import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 快鸟物流查询服务
 * <p>
 * 3831775044640 韵达快递(YD)
 */
public class ExpressService {

    private ExpressProperties properties;

    public ExpressProperties getProperties() {
        return properties;
    }

    public void setProperties(ExpressProperties properties) {
        this.properties = properties;
    }

    /**
     * 获取物流供应商名
     *
     * @param vendorCode
     * @return
     */
    public String getVendorName(String vendorCode) {
        for (Map<String, String> item : properties.getVendors()) {
            if (item.get("code").equals(vendorCode)) {
                return item.get("name");
            }
        }
        return null;
    }

    public String getVendorCode(String vendorName) {
        for (Map<String, String> item : properties.getVendors()) {
            if (item.get("name").equals(vendorName)) {
                return item.get("code");
            }
        }
        return null;
    }

    public String getCustomerInfo(String vendorCode) {
        for (Map<String, String> item : properties.getVendors()) {
            if (item.get("code").equals(vendorCode)) {
                switch (vendorCode) {
                    case "YTO":
                        String customerName = item.get("costumerName");
                        String monthCode = item.get("monthCode");
                        if (customerName != null && !customerName.equals("") && monthCode != null && !monthCode.equals("")) {
                            return "'CustomerName':'" + customerName + "','MonthCode':'" + monthCode + "',";
                        } else {
                            return null;
                        }
                    default:
                        return null;
                }
            }
        }
        return null;
    }

    /**
     * method: orderOnlineByJson
     *
     * @Description: Json方式 电子面单
     * @param: [
     * shipperCode 快递公司编码,
     * orderCode 订单编号,
     * payType 邮费支付方式:1-现付，2-到付，3-月结，4-第三方支付,
     * expType 快递类型：1-标准快件,
     * receiverName 收件人,
     * receiverMobile 手机,
     * receiverProvinceName 收件省（如广东省，不要缺少“省”）	,
     * receiverCityName 收件市（如深圳市，不要缺少“市”）,
     * receiverExpAreaName 收件区（如福田区，不要缺少“区”或“县”） O,
     * receiverAddress 收件人详细地址,
     * senderName 发件人,
     * senderMobile 手机,
     * senderProvinceName 发件省（如广东省，不要缺少“省”）,
     * senderCityName 发件市（如深圳市，不要缺少“市”）,
     * senderExpAreaName 发件区（如福田区，不要缺少“区”或“县”） O,
     * senderAddress 发件人详细地址,
     * goodsName 商品名称]
     * @return: java.lang.String
     * @author: yh
     * @date: 2018/8/7 10:43
     */
    public String orderOnlineByJson(
        String shipperCode,
        String orderCode,
        Integer payType,
        Integer expType,
        String receiverName,
        String receiverMobile,
        String receiverProvinceName,
        String receiverCityName,
        String receiverExpAreaName,
        String receiverAddress,
        String senderName,
        String senderMobile,
        String senderProvinceName,
        String senderCityName,
        String senderExpAreaName,
        String senderAddress,
        String goodsName,
        String quantity) throws Exception {
        String MonthCode = "4740146781";
        String requestData = "{";
        String customerInfo = this.getCustomerInfo(shipperCode);
        if (customerInfo != null && !customerInfo.equals("")) {
            requestData += customerInfo;
        }
        if(payType == 3){
            requestData += "'OrderCode': '" + orderCode + "'," + "'ShipperCode':'" + shipperCode + "'," + "'PayType':'" + payType + "'," + "'MonthCode':'" + MonthCode + "'," + "'ExpType':" + expType + "," + "'Cost':1.0," + "'OtherCost':1.0,"
                    + "'Sender':" + "{" +
                    //                "'Company':'LV',"+
                    "'Name':'" + senderName + "','Mobile':'" + senderMobile + "'," + "'PostCode':'000000'," + "'ProvinceName':'" + senderProvinceName + "','CityName':'" + senderCityName + "','ExpAreaName':'"
                    + senderExpAreaName + "','Address':'" + senderAddress + "'}," + "'Receiver':" + "{" + "'Name':'" + receiverName + "','Mobile':'" + receiverMobile + "'," + "'PostCode':'000000',"
                    + "'ProvinceName':'" + receiverProvinceName + "','CityName':'" + receiverCityName + "','ExpAreaName':'" + receiverExpAreaName + "','Address':'" + receiverAddress + "'}," + "'Commodity':"
                    + "[{" + "'GoodsName':'" + goodsName + "'" +
                    //                ",'Goodsquantity':1,'GoodsWeight':1.0"+
                    "}]," +
                    //                "'Weight':1.0," +
                    "'Quantity':" + quantity + "," +
                    //                "'Volume':0.0," +
                    "'Remark':'小心轻放'," + "'IsNotice':1,'IsReturnPrintTemplate':1}";

        }else{
            requestData += "'OrderCode': '" + orderCode + "'," + "'ShipperCode':'" + shipperCode + "'," + "'PayType':" + payType + "," + "'ExpType':" + expType + "," + "'Cost':1.0," + "'OtherCost':1.0,"
                    + "'Sender':" + "{" +
                    //                "'Company':'LV',"+
                    "'Name':'" + senderName + "','Mobile':'" + senderMobile + "'," + "'PostCode':'000000'," + "'ProvinceName':'" + senderProvinceName + "','CityName':'" + senderCityName + "','ExpAreaName':'"
                    + senderExpAreaName + "','Address':'" + senderAddress + "'}," + "'Receiver':" + "{" + "'Name':'" + receiverName + "','Mobile':'" + receiverMobile + "'," + "'PostCode':'000000',"
                    + "'ProvinceName':'" + receiverProvinceName + "','CityName':'" + receiverCityName + "','ExpAreaName':'" + receiverExpAreaName + "','Address':'" + receiverAddress + "'}," + "'Commodity':"
                    + "[{" + "'GoodsName':'" + goodsName + "'" +
                    //                ",'Goodsquantity':1,'GoodsWeight':1.0"+
                    "}]," +
                    //                "'Weight':1.0," +
                    "'Quantity':" + quantity + "," +
                    //                "'Volume':0.0," +
                    "'Remark':'小心轻放'," + "'IsNotice':1,'IsReturnPrintTemplate':1}";
        }

        Map<String, String> params = new HashMap<>();
        params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
        params.put("EBusinessID", properties.getAppId());
        params.put("RequestType", "1007");
        String dataSign = encrypt(requestData, properties.getAppKey(), "UTF-8");
        params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
        params.put("DataType", "2");

        String result = null;
        try {
            result = HttpUtil.sendPost(properties.getOrderUrl(), params);
        }

        catch (Exception e) {
            e.printStackTrace();
        }
        //根据公司业务处理返回的信息......
        return result;
    }

    /**
     * Json方式 查询订单物流轨迹
     *
     * @throws Exception
     */
    public String getOrderTracesByJson(String expCode, String expNo) throws Exception {
        if (!properties.isEnable()) {
            return null;
        }
        String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";

        Map<String, String> params = new HashMap<String, String>();
        params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
        params.put("EBusinessID", properties.getAppId());
        params.put("RequestType", "1002");
        String dataSign = encrypt(requestData, properties.getAppKey(), "UTF-8");
        params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
        params.put("DataType", "2");

        String result = HttpUtil.sendPost(properties.getQueryUrl(), params);

        //根据公司业务处理返回的信息......

        return result;
    }

    /**
     * 快递公司编码 ShipperCode
     * 订单编号	OrderCode
     * 快递单号	ExpNo
     */
    //取消电子面单操作
    public String orderCancelByJson(String ShipperCode, String OrderCode, String ExpNo) throws Exception {
        if (!properties.isEnable()) {
            return null;
        }
        String requestData = "{";
        String customerInfo = this.getCustomerInfo(ShipperCode);
        if (customerInfo != null && !customerInfo.equals("")) {
            requestData += customerInfo;
        }
        requestData += "'ShipperCode':'" + ShipperCode + "','OrderCode':'" + OrderCode + "','ExpNo':'" + ExpNo + "'}";

        Map<String, String> params = new HashMap<>();
        params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
        params.put("EBusinessID", properties.getAppId());
        params.put("RequestType", "1147");
        String dataSign = encrypt(requestData, properties.getAppKey(), "UTF-8");
        params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
        params.put("DataType", "2");

        String result = HttpUtil.sendPost("http://api.kdniao.com/api/EOrderService", params);

        return result;
    }

    /**
     * MD5加密
     *
     * @param str     内容
     * @param charset 编码方式
     * @throws Exception
     */
    private String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuffer sb = new StringBuffer(32);
        for (int i = 0; i < result.length; i++) {
            int val = result[i] & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }

    /**
     * Sign签名生成
     *
     * @param content  内容
     * @param keyValue Appkey
     * @param charset  编码方式
     * @return DataSign签名
     */
    private String encrypt(String content, String keyValue, String charset) {
        if (keyValue != null) {
            content = content + keyValue;
        }
        byte[] src = new byte[0];
        try {
            src = MD5(content, charset).getBytes(charset);
            return Base64Utils.encodeToString(src);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     *  * 判断字符串中是否包含中文
     *  * @param str
     *  * 待校验字符串
     *  * @return 是否为中文
     *  * @warn 不能校验是否为中文标点符号
     *  
     */
    public boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }
}
